package org.lex.io.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Unzip {
	public static void main(String[] args) throws Exception {
		File output = new File("C:\\_liuex\\tmp\\");
		File input = new File(output, "tmp.zip");

		Unzip zip = new Unzip(input, new File(output, "123"));
		zip.unzip();
	}

	private Logger log = LoggerFactory.getLogger(Unzip.class);
	private File folder = null;
	private File zipFile = null;

	public Unzip(File zipFile, File folder) {
		this.folder = folder;
		this.zipFile = zipFile;
	}

	public void unzip() throws IOException {
		long startTime = System.currentTimeMillis();
		log.info("Unzip input file=" + zipFile);
		log.info("Unzip output folder=" + folder);

		InputStream in = new BufferedInputStream(new FileInputStream(zipFile));
		ZipInputStream zip = new ZipInputStream(in);
		int fileCount = 0;
		int folderCount = 0;
		while (true) {
			ZipEntry entry = zip.getNextEntry();
			if (null == entry) {
				long time = System.currentTimeMillis() - startTime;
				log.info("unzip finished: " + folderCount + " folders, " + fileCount + " files in " + (((float) time) / 1000) + " s");
				break;
			}
			String name = entry.getName();
			File file = new File(folder, name);
			if (entry.isDirectory()) {
				log.info("Extracting folder:\t" + file);
				folderCount++;
				FileUtils.createFolder(file);
			} else {
				log.info("Extracting   file:\t" + file);
				fileCount++;
				FileUtils.createFile(file);

				OutputStream out = new BufferedOutputStream(new FileOutputStream(file));
				int ch = 0;
				while (zip.available() > 0) {
					ch = zip.read();
					if (-1 != ch) {
						out.write(ch);
					}
				}
				out.flush();
				out.close();
			}
		}
		zip.close();
	}
}
